package run

import (
	"fmt"
	"github.com/Unixeno/islands/pb"
	"github.com/docker/go-units"
)

type CgroupsSetting struct {
	memoryString      string
	memoryReservation string
	memorySwap        string
	oomKillDisable    bool
	kernelMemory      string

	cpuShares          int64
	cpuPeriod          int64
	cpuRealtimePeriod  int64
	cpuRealtimeRuntime int64
	cpuQuota           int64
	cpusetCpus         string
	cpusetMems         string
	swappiness         int64
	cgroupParent       string
}

func parse() (*pb.Resources, error) {
	var memory int64
	var err error
	if cgroupsSetting.memoryString != "" {
		memory, err = units.RAMInBytes(cgroupsSetting.memoryString)
		if err != nil {
			return nil, err
		}
	}

	var memoryReservation int64
	if cgroupsSetting.memoryReservation != "" {
		memoryReservation, err = units.RAMInBytes(cgroupsSetting.memoryReservation)
		if err != nil {
			return nil, err
		}
	}

	var memorySwap int64
	if cgroupsSetting.memorySwap != "" {
		if cgroupsSetting.memorySwap == "-1" {
			memorySwap = -1
		} else {
			memorySwap, err = units.RAMInBytes(cgroupsSetting.memorySwap)
			if err != nil {
				return nil, err
			}
		}
	}

	var kernelMemory int64
	if cgroupsSetting.kernelMemory != "" {
		kernelMemory, err = units.RAMInBytes(cgroupsSetting.kernelMemory)
		if err != nil {
			return nil, err
		}
	}

	swappiness := cgroupsSetting.swappiness
	if swappiness != -1 && (swappiness < 0 || swappiness > 100) {
		return nil, fmt.Errorf("invalid value: %d. Valid memory swappiness range is 0-100", swappiness)
	}

	resources := &pb.Resources{
		CgroupParent:       cgroupsSetting.cgroupParent,
		Memory:             memory,
		MemoryReservation:  memoryReservation,
		MemorySwap:         memorySwap,
		MemorySwappiness:   swappiness,
		KernelMemory:       kernelMemory,
		OomKillDisable:     cgroupsSetting.oomKillDisable,
		CPUShares:          cgroupsSetting.cpuShares,
		CPUPeriod:          cgroupsSetting.cpuPeriod,
		CpusetCpus:         cgroupsSetting.cpusetCpus,
		CpusetMems:         cgroupsSetting.cpusetMems,
		CPUQuota:           cgroupsSetting.cpuQuota,
		CPURealtimePeriod:  cgroupsSetting.cpuRealtimePeriod,
		CPURealtimeRuntime: cgroupsSetting.cpuRealtimeRuntime,
	}

	return resources, nil
}
